package io.github.uicdb.et.net;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import org.checkerframework.common.value.qual.IntRange;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

@Getter
@Setter
public final class AttachedData {
    public static final Codec<AttachedData> CODEC = RecordCodecBuilder.create(ins -> ins.group(
            Codec.INT.optionalFieldOf("amount",1).forGetter(o -> o.amount),
            Codec.INT.optionalFieldOf("remainTicks",1).forGetter(o -> o.remainTicks),
            Codec.INT.optionalFieldOf("attacker",-1).forGetter(o -> o.attacker)
    ).apply(ins, AttachedData::new));
    public static final StreamCodec<ByteBuf, AttachedData> STREAM_CODEC = StreamCodec.composite(
            ByteBufCodecs.VAR_INT,
            o -> o.amount,
            ByteBufCodecs.VAR_INT,
            o -> o.remainTicks,
            ByteBufCodecs.VAR_INT,
            o -> o.attacker,
            AttachedData::new
    );

    private int amount;
    private int remainTicks;
    private int attacker;

    AttachedData(int amount, int remainTicks, int attacker) {
        this.amount = amount;
        this.remainTicks = remainTicks;
        this.attacker = attacker;
    }


    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (obj == null || obj.getClass() != this.getClass()) return false;
        var that = (AttachedData) obj;
        return this.amount == that.amount &&
                this.remainTicks == that.remainTicks && this.attacker == that.attacker;
    }

    @Override
    public int hashCode() {
        return Objects.hash(amount, remainTicks, attacker);
    }

    @Override
    public String toString() {
        return "AttachedData[" +
                "amount=" + amount + ", " +
                "remainTicks=" + remainTicks + ", " +
                "attacker=" + attacker + ']';
    }

    public AttachedData copy() {
        return new AttachedData(amount, remainTicks, attacker);
    }

    public void set(int amount, int tick, @Nullable LivingEntity attacker) {
        this.amount = amount;
        this.remainTicks = tick;
        if (attacker != null)
            this.attacker = attacker.getId();
        else this.attacker = -1;
    }
    public @Nullable LivingEntity getAttacker(Level level) {
        if(attacker == -1)
            return null;
        var e=level.getEntity(attacker);
        if (e instanceof LivingEntity livingEntity)
            return livingEntity;
        return null;
    }
    public void set(int amount, int tick,int attacker) {
        this.amount = amount;
        this.remainTicks = tick;
        this.attacker = attacker;
    }
}
